Skip to content

feat(provider): add Claude SDK "auto" permission mode as 4th runtime mode - #137

Merged
Ecko95 merged 4 commits into
gitsfrom
feat/claude-auto-permission-mode
Jul 10, 2026
Merged

feat(provider): add Claude SDK "auto" permission mode as 4th runtime mode#137
Ecko95 merged 4 commits into
gitsfrom
feat/claude-auto-permission-mode

Conversation

@Ecko95

@Ecko95 Ecko95 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Closes #135.

What

Adds the Claude Agent SDK's native permissionMode: "auto" as a 4th runtime permission mode alongside approval-required, auto-accept-edits, and full-access. "auto" lets the SDK's model classifier auto-approve safe tool calls while still gating risky ones — a middle rung between ask/plan and full yolo. No allowDangerouslySkipPermissions is set. Reimplemented natively (not cherry-picked from upstream pingdotgg#3628).

Changes

  • packages/contracts/src/orchestration.ts — add "auto" to the RuntimeMode literal (single source of truth). DEFAULT_RUNTIME_MODE unchanged (full-access).
  • apps/server/src/provider/Layers/ClaudeAdapter.ts — map "auto" → permissionMode: "auto". allowDangerouslySkipPermissions stays unset (only full-access/bypassPermissions sets it).
  • apps/web/src/components/chat/ChatComposer.tsx + CompactComposerControlsMenu.tsx — add "Auto" to both permission-mode pickers.
  • apps/server/src/provider/Layers/CodexSessionRuntime.tssecurity guard: the web picker isn't engine-filtered, so "auto" can be selected on a Codex thread. Without an explicit case "auto": it would fall into default: = danger-full-access/approvalPolicy: "never". Added case "auto": (stacked with auto-accept-edits) in both the thread-config and turn-sandbox switches, so Codex treats "auto" as the conservative on-request/workspace-write policy.
  • apps/mobile/.../ThreadComposer.tsx + NewTaskDraftScreen.tsx — fix the runtime-mode subtitle so an "auto" thread isn't mislabeled "Full access" (display-only; mobile still can't select auto — out of scope).
  • Tests: ClaudeAdapter.test.ts (auto → permissionMode: "auto", allowDangerouslySkipPermissions === undefined), CodexSessionRuntime.test.ts (auto → conservative policy — guards the security case).

Security / interaction with authz

  • Cursor and OpenCode use equality checks (=== "full-access" / === "approval-required"), so "auto" lands in their existing conservative "ask" branch by construction — other engines unaffected.
  • Server-side deny-by-default authorization is unchanged and independent: checkActorAuthorization (commandInvariants.ts) gates commands by actor/session-role with zero runtimeMode conditional. A server-denied command is denied identically under "auto" as any other mode; a thread-scoped session still cannot self-approve.
  • Known, intended tradeoff: in auto mode the SDK's classifier auto-approves/denies some safe tool calls before they reach GITS's canUseTool gate, so those calls won't appear in GITS's local approval audit trail. This is inherent to what the issue asked for ("let the SDK auto-approve safe tool calls"); structural server authz and confinement (git-shim, allowed-root) still apply regardless of SDK mode.

Verification

  • Local: forced typecheck (turbo run typecheck --force) 14/14 packages; ClaudeAdapter.test.ts 64/64; CodexSessionRuntime.test.ts 18/18; oxlint/oxfmt clean on touched paths.
  • Adversarial review (correctness + security lenses): no bypass; verified allowDangerouslySkipPermissions never set, Codex/Cursor/OpenCode all safe, authz mode-independent. Two review findings fixed (Codex "auto" test + mobile mislabel).
  • Live e2e (headless server built from this branch, Playwright + direct sqlite):
    • Picker exposes "Auto"; selecting it persists runtime_mode = "auto" through the real command→event→projection pipeline; other modes still round-trip.
    • commandInvariants.test.ts 16/16 — server authz provably mode-independent.
    • A live claude-sonnet-4-6 turn in auto mode ran a read-only tool call auto-approved by the SDK classifier with no GITS approval prompt, correct result, real API cost — confirming SDK-native auto behavior end-to-end.

Caveat (follow-up candidate, not blocking)

The SDK enforces its own per-model gate: claude-opus-4-8 rejects permissionMode: "auto" with "auto mode unavailable for this model" (surfaced as the thread's last_error; the string originates in the vendored SDK binary, not this code). A nice follow-up would be to surface that gracefully in the UI (or disable "auto" in the picker for models that don't support it) so it doesn't read as a silent failure. Also deferred: exposing "auto" as a selectable option in the mobile composer (this PR only fixes the mobile label).

…mode

Expose the Claude Agent SDK's native permissionMode "auto" as a fourth
RuntimeMode. The SDK's model classifier auto-approves safe tool calls while
still gating risky ones; allowDangerouslySkipPermissions is never set.

Includes a security guard so "auto" selected on a Codex thread maps to the
conservative on-request/workspace-write policy instead of falling through to
danger-full-access, and a mobile label fix so an auto thread isn't shown as
"Full access". Server-side actor authorization is unchanged and remains
mode-independent.

Closes #135

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S labels Jul 9, 2026
Codex Peer and others added 3 commits July 10, 2026 01:39
Add a buildThreadStartParams assertion that runtimeMode "auto" maps to the
conservative on-request/workspace-write policy (not the danger default),
closing the thread-start coverage gap alongside the existing turn-start test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Ecko95
Ecko95 merged commit a4a0bac into gits Jul 10, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant